package org.jetnuke.modules.blog.utils;

import org.apache.log4j.Logger;

import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import net.jforum.entities.User;
import net.jforum.util.concurrent.Task;
import net.jforum.util.concurrent.executor.QueuedExecutor;

import org.apache.commons.lang.StringUtils;
import org.apache.xmlrpc.XmlRpcException;
import org.jetnuke.dao.BlogCategoryDAO;
import org.jetnuke.dao.BlogPostDAO;
import org.jetnuke.dao.BlogUserSettingsDAO;
import org.jetnuke.dao.DataAccessDriver;
import org.jetnuke.entities.BlogCategory;
import org.jetnuke.entities.BlogPost;
import org.jetnuke.entities.BlogUserSettings;
import org.jetnuke.entities.MainConfig;
import org.jetnuke.repository.MainConfigRepository;

public class BloggerAPIHandler extends BaseAPIHandler {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger
			.getLogger(BloggerAPIHandler.class);

	private static final String MEMBER_EMAIL = "email";
	private static final String MEMBER_NICKNAME = "nickname";
	private static final String MEMBER_USERID = "userid";
	private static final String MEMBER_URL = "url";
	private static final String MEMBER_FIRSTNAME = "firstname";
	private static final String MEMBER_LASTNAME = "lastname";

	public Object getUserInfo(String appkey, String username, String password)
			throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("getUserInfo(String, String, String) - start"); //$NON-NLS-1$
		}

		User user = validate(username, password);
		if (user != null) {
			Hashtable userinfo = new Hashtable();

			userinfo.put(MEMBER_EMAIL, user.getEmail());
			userinfo.put(MEMBER_NICKNAME, username);
			userinfo.put(MEMBER_USERID, String.valueOf(user.getId()));
			// userinfo.put(MEMBER_URL, _blog.getBlogURL()); //TODO

			String _ownerName = username;
			int _split = _ownerName.indexOf(" ");
			if (_split > 0) {
				userinfo.put(MEMBER_FIRSTNAME, _ownerName.substring(0, _split));
				userinfo.put(MEMBER_LASTNAME, _ownerName.substring(_split + 1));
			} else {
				userinfo.put(MEMBER_FIRSTNAME, "jetnuke");
				userinfo.put(MEMBER_LASTNAME, _ownerName);
			}

			if (logger.isDebugEnabled()) {
				logger.debug("getUserInfo(String, String, String) - end"); //$NON-NLS-1$
			}
			return userinfo;
		} else {
			throw new XmlRpcException(AUTHORIZATION_EXCEPTION,
					AUTHORIZATION_EXCEPTION_MSG);
		}

	}

	public boolean editPost(String appkey, String postid, String userid,
			String password, String content, boolean publish) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("editPost(String, String, String, String, String, boolean) - start"); //$NON-NLS-1$
		}

		User user = validate(userid, password);

		String title = "";

		if (content.indexOf("<title>") != -1) {
			title = content.substring(content.indexOf("<title>") + 7, content
					.indexOf("</title>"));
			content = StringUtils.replace(content, "<title>" + title
					+ "</title>", "");
		}
		if (title == null)
			title = "";
		BlogPostDAO bpm = DataAccessDriver.getInst().newBlogPostDAO();
		BlogPost blogPost = bpm.retrieveByPK(Integer.parseInt(postid));
		if (blogPost.getAID() == user.getId()) {
			blogPost.setPOSTTITLE(title);
			blogPost.setPOSTCONTENT(content);
			blogPost.setPOSTMODIFIED(new GregorianCalendar().getTime());
			bpm.update(blogPost);
		}

		if (logger.isDebugEnabled()) {
			logger
					.debug("editPost(String, String, String, String, String, boolean) - end"); //$NON-NLS-1$
		}
		return true;
	}

	public Object getUsersBlogs(String appkey, String userid, String password)
			throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("getUsersBlogs(String, String, String) - start"); //$NON-NLS-1$
		}

		User user = validate(userid, password);
		if (user != null) {
			try {

				Hashtable blog = new Hashtable(3);

				String blogid = MainConfigRepository.getMainConfig()
						.getNUKEURL()
						+ "do/blog/user?id=" + user.getId();
				blog.put("blogid", blogid);
				blog.put("url", blogid); // TODO
				BlogUserSettingsDAO busd = DataAccessDriver.getInst()
						.newBlogUserSettingsDAO();
				BlogUserSettings bus = busd.retrieveByPk(user.getId());
				blog.put("blogName", bus.getTITLE());

				Vector result = new Vector();
				result.add(blog);

				if (logger.isDebugEnabled()) {
					logger.debug("getUsersBlogs(String, String, String) - end"); //$NON-NLS-1$
				}
				return result;
			} catch (Exception e) {
				logger.error("getUsersBlogs(String, String, String)", e); //$NON-NLS-1$

				String msg = "ERROR in BlooggerAPIHander.getUsersBlogs";
				throw new XmlRpcException(UNKNOWN_EXCEPTION, msg);
			}
		} else {
			throw new XmlRpcException(AUTHORIZATION_EXCEPTION,
					AUTHORIZATION_EXCEPTION_MSG);
		}
	}

	public String newPost(String appkey, String blogid, String userid,
			String password, String content, int publish) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("newPost(String, String, String, String, String, int) - start"); //$NON-NLS-1$
		}

		String returnString = newPost(appkey, blogid, userid, password,
				content, (publish == 1 ? true : false));
		if (logger.isDebugEnabled()) {
			logger
					.debug("newPost(String, String, String, String, String, int) - end"); //$NON-NLS-1$
		}
		return returnString;
	}

	public String newPost(String appkey, String blogid, String userid,
			String password, String content, boolean publish) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("newPost(String, String, String, String, String, boolean) - start"); //$NON-NLS-1$
		}

		User user = validate(userid, password);
		if (user != null) {
			BlogPost bp = null;
			BlogPostDAO bpm = DataAccessDriver.getInst().newBlogPostDAO();

			bp = new BlogPost();
			BlogCategoryDAO bcm = DataAccessDriver.getInst()
					.newBlogCategoryDAO();
			List categories = bcm.selectByUser(user.getId());

			String title = "";

			if (content.indexOf("<title>") != -1) {
				title = content.substring(content.indexOf("<title>") + 7,
						content.indexOf("</title>"));
				content = StringUtils.replace(content, "<title>" + title
						+ "</title>", "");
			}

			int category = ((BlogCategory) categories.get(0)).getID();

			bp.setAID(user.getId());
			bp.setCOMMENTSTATUS("open");
			bp.setPOSTDATE(new GregorianCalendar().getTime());
			bp.setPOSTCATEGORY(category);
			bp.setPOSTCONTENT(content);
			bp.setPOSTEXCERPT("");
			bp.setPOSTPASSWORD("");

			bp.setPOSTSTATUS("publish");
			bp.setGUID(" ");
			bp.setPOSTTITLE(title);
			bp.setPINGSTATUS("open");
			bp.setTOPING("");
			final int id;
			bp.setPINGED("");

			id = bpm.addNew(bp);
			bp.setID(id);
			bp.setGUID(MainConfigRepository.getMainConfig().getNUKEURL()
					+ "do/blog/show_page?id=" + id);
			bpm.update(bp);

			MainConfig config = MainConfigRepository.getMainConfig();
			final String url = config.getNUKEURL();
			QueuedExecutor.getInstance().execute(new Task() {

				public Object execute() throws Exception {
					if (logger.isDebugEnabled()) {
						logger.debug("$Task.execute() - start"); //$NON-NLS-1$
					}

					try {

						BlogUtils.doTrackback(url, id);
						BlogUtils.doPingback(url, id);
					} catch (Throwable e) {
						logger.error("$Task.execute()", e); //$NON-NLS-1$

						if (logger.isDebugEnabled()) {
							logger.debug("$Task.execute() - end"); //$NON-NLS-1$
						}
						return "FAILURE";
					}

					if (logger.isDebugEnabled()) {
						logger.debug("$Task.execute() - end"); //$NON-NLS-1$
					}
					return "SUCCESS";
				}
			});//

			String returnString = String.valueOf(id);
			if (logger.isDebugEnabled()) {
				logger
						.debug("newPost(String, String, String, String, String, boolean) - end"); //$NON-NLS-1$
			}
			return returnString;
		} else {
			throw new XmlRpcException(AUTHORIZATION_EXCEPTION,
					AUTHORIZATION_EXCEPTION_MSG);
		}
	}

	public boolean deletePost(String appkey, String postid, String userid,
			String password, boolean publish) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("deletePost(String, String, String, String, boolean) - start"); //$NON-NLS-1$
		}

		throw new XmlRpcException(UNSUPPORTED_EXCEPTION,
				UNSUPPORTED_EXCEPTION_MSG);
	}

	public Object getPost(String appkey, String blogid, String userid,
			String password) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("getPost(String, String, String, String) - start"); //$NON-NLS-1$
		}

		User user = validate(userid, password);
		if (user != null) {
			BlogPostDAO bpm = DataAccessDriver.getInst().newBlogPostDAO();

			List ls = bpm.retrieveByUserOrdered(user.getId());
			if (!ls.isEmpty()) {
				Map result = createStruct((BlogPost) ls.get(0));

				if (logger.isDebugEnabled()) {
					logger
							.debug("getPost(String, String, String, String) - end"); //$NON-NLS-1$
				}
				return result;
			}

			if (logger.isDebugEnabled()) {
				logger.debug("getPost(String, String, String, String) - end"); //$NON-NLS-1$
			}
			return null;
		} else {
			throw new XmlRpcException(AUTHORIZATION_EXCEPTION,
					AUTHORIZATION_EXCEPTION_MSG);
		}

	}

	public Object getRecentPosts(String appkey, String blogid, String userid,
			String password, int numposts) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("getRecentPosts(String, String, String, String, int) - start"); //$NON-NLS-1$
		}

		User user = validate(userid, password);
		if (user != null) {
			try {
				Vector results = new Vector();
				BlogPostDAO bpm = DataAccessDriver.getInst().newBlogPostDAO();
				List entries = bpm.retrieveByUserOrdered(user.getId());
				Iterator it = entries.iterator();
				int counter = 0;
				while (it.hasNext()) {
					BlogPost blogPost = (BlogPost) it.next();
					Map result = createStruct(blogPost);
					results.add(result);
					counter++;
					if (counter > numposts)
						break;
				}

				if (logger.isDebugEnabled()) {
					logger
							.debug("getRecentPosts(String, String, String, String, int) - end"); //$NON-NLS-1$
				}
				return results;
			} catch (Exception e) {
				logger
						.error(
								"getRecentPosts(String, String, String, String, int)", e); //$NON-NLS-1$

				String msg = "ERROR in BlooggerAPIHander.getRecentPosts";

				throw new XmlRpcException(UNKNOWN_EXCEPTION, msg);
			}
		} else {
			throw new XmlRpcException(AUTHORIZATION_EXCEPTION,
					AUTHORIZATION_EXCEPTION_MSG);
		}
	}

	protected Map createStruct(BlogPost blogPost) {
		if (logger.isDebugEnabled()) {
			logger.debug("createStruct(BlogPost) - start"); //$NON-NLS-1$
		}

		Hashtable result = new Hashtable();
		result.put("dateCreated", blogPost.getPOSTDATE());
		result.put("userid", String.valueOf(blogPost.getAID()));
		result.put("postid", String.valueOf(blogPost.getID()));
		result.put("content", blogPost.getPOSTCONTENT());

		if (logger.isDebugEnabled()) {
			logger.debug("createStruct(BlogPost) - end"); //$NON-NLS-1$
		}
		return result;
	}

	public boolean setTemplate(String appkey, String blogid, String userid,
			String password, String template, String templateType)
			throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("setTemplate(String, String, String, String, String, String) - start"); //$NON-NLS-1$
		}

		throw new XmlRpcException(UNSUPPORTED_EXCEPTION,
				UNSUPPORTED_EXCEPTION_MSG);
	}

	public String getTemplate(String appkey, String blogid, String userid,
			String password, String templateType) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("getTemplate(String, String, String, String, String) - start"); //$NON-NLS-1$
		}

		throw new XmlRpcException(UNSUPPORTED_EXCEPTION,
				UNSUPPORTED_EXCEPTION_MSG);
	}
}
